package com.rengwuxian.wecompose.activity

import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.widget.Toast
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.layout
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat
import cn.hutool.http.HttpRequest
import cn.hutool.json.JSONUtil
import com.jiayou.BroadcastPackage
import com.jiayou.SimpleDataPackageImpl
import com.jiayou.emnu.FrameType
import com.jiayou.server.ClientSocketServer
import com.jiayou.session.DefaultClientSocketSession
import com.rengwuxian.wecompose.data.Chat
import com.rengwuxian.wecompose.data.Msg
import com.rengwuxian.wecompose.entity.User
import com.rengwuxian.wecompose.mv.IndexViewModel
import com.rengwuxian.wecompose.mv.WeViewModel
import com.rengwuxian.wecompose.ui.Home
import com.rengwuxian.wecompose.ui.Index
import com.rengwuxian.wecompose.ui.theme.WeTheme
import kotlinx.coroutines.*
import java.net.InetSocketAddress
import java.util.*
import kotlin.concurrent.thread
import kotlin.math.roundToInt

class MainActivity : AppCompatActivity() {
    companion object {
        @SuppressLint("StaticFieldLeak")
        lateinit var context: Context
        lateinit var indexMv: IndexViewModel
        lateinit var viewModel: WeViewModel
        lateinit var uri: String
        lateinit var client: ClientSocketServer<String, String, String>
        var userInfo = hashMapOf<String, Any>()
        var isRunning = true
    }

    private val properties = Properties()

    @DelicateCoroutinesApi
    @ExperimentalComposeUiApi
    @ExperimentalAnimationApi
    override fun onCreate(savedInstanceState: Bundle?) {
        runBlocking {
            withContext(Dispatchers.IO) {
                client = ClientSocketServer(
                    inetSocketAddress = InetSocketAddress("jiayou.art", 9000),
                    clientSocketSession = DefaultClientSocketSession()
                )
            }
        }

        super.onCreate(savedInstanceState)
        val viewModel: WeViewModel by viewModels()
        MainActivity.viewModel = viewModel
        context = this
        properties.load(application.assets.open("im.properties"))
        uri = properties["im.uri"].toString() + ":" + properties["im.port"].toString()
        WindowCompat.setDecorFitsSystemWindows(window, false)
        setContent {
            val indexViewModel: IndexViewModel by remember { mutableStateOf(IndexViewModel()) }
            indexMv = indexViewModel
            client.setReceiveHandler {
                var message = ""
                val frame = it.getFrame()
                GlobalScope.launch {
                    when (it.getFrameType()) {
                        FrameType.AUTHENTICATIONFAILD -> {
                            message = "认证失败!请重试"
                            withContext(Dispatchers.Main) {
                                Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
                            }
                            isRunning = false
                            delay(1000)
                            client.stop()
                            finishAffinity()
                        }
                        FrameType.AUTHENTICATIONSUCCESS -> message = "欢迎回来 - v -"
                        FrameType.SYSTEM -> message = "系统提示："
                        FrameType.BROADCAST -> {
                            message = "广播消息：" + (frame as BroadcastPackage).data
                        }
                        FrameType.REPEATUSER -> {
                            message = "你的账户已登录，请退出该账户后登录！"
                            withContext(Dispatchers.Main) {
                                Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
                            }
                            isRunning = false
                            delay(1000)
                            client.stop()
                            finish()
                        }
                        FrameType.MESSAGE -> {
                            message = (frame as SimpleDataPackageImpl).data()
//                            viewModel.chats.find { item -> item.friend.id == frame.from() }!!.msgs.add(
//                                Msg(
//                                    viewModel.chats.find { item -> item.friend.id == frame.from() }!!.friend, message
//                                ).apply { read = true }
//                            )
//                            viewModel.chats.forEach { iii -> println(iii) }


                            val currentChat = viewModel.currentChat
                            if (currentChat != null) {
                                if (currentChat.friend.id == frame.from()) {
                                    currentChat.msgs.add(Msg(currentChat.friend, message).apply { read = true })
                                }
                                viewModel.currentSize += 1
                            }
//                            println("list1111 ->" +  viewModel.chats)
                        }
                        else -> {
                        }
                    }
                    withContext(Dispatchers.Main) {
                        Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
                    }
                }
            }
            WeTheme(theme = viewModel.theme) {
                if (!indexViewModel.logined) {
                    Index(indexViewModel)
                } else {
                    Home(indexMv)
                }
            }
        }
        thread {
            while (true) {
                Thread.sleep(1000)
                if (indexMv.logined) {
                    this.initFriends()
                    break
                }
                Thread.sleep(3000)
            }
        }
    }

    override fun onBackPressed() {
        client.stop()
        val viewModel: WeViewModel by viewModels()
        if (viewModel.openModule != null) {
            viewModel.endChat()
        } else {
            super.onBackPressed()
        }
    }


    private fun initFriends() {
        thread {
            while (isRunning) {
                runBlocking {
                    val parse = JSONUtil.parseObj(
                        HttpRequest.get("http://${uri}/im/relation/getRelation")
                            .form(
                                mapOf(
                                    "id" to userInfo["username"]
                                )
                            )
                            .header("auth", "73913da7-508b-4646-b8ae-ef6458f41153")
                            .execute()
                            .body()
                    )

                    if (parse["code"].toString().toInt() == 200) {
                        val list = ArrayList<User>()
                        JSONUtil.parseArray(parse["data"]).forEach {
                            val obj = JSONUtil.parseObj(it)
                            list.add(
                                User(
                                    obj["username"].toString(),
                                    obj["petname"].toString(),
                                    if (obj["gender"].toString().toInt() == 0) "女" else "男",
                                    obj["description"].toString(),
                                    obj["img"].toString()
                                )
                            )
                        }
                        indexMv.friends.clear()
                        indexMv.friends.addAll(list)
//                        println(indexMv.friends)
                    }
                }
                getMsgList()
                Thread.sleep(3000)
            }
        }
    }


    private fun getMsgList() {
        viewModel.chats.clear()
        indexMv.friends.forEach {
            thread {
                runBlocking {
                    val parse = JSONUtil.parseObj(
                        HttpRequest.get("http://${uri}/im/chat/getMessage")
                            .form(
                                mapOf(
                                    "id1" to userInfo["username"],
                                    "id2" to it.id
                                )
                            )
                            .header("auth", "73913da7-508b-4646-b8ae-ef6458f41153")
                            .execute()
                            .body()
                    )
                    val msgList = arrayListOf<Msg>()
                    JSONUtil.parseArray(parse["data"]).forEach {
                        val obj = JSONUtil.parseObj(it)
                        if (obj["id1"].toString() == userInfo["username"]) {
                            msgList.add(
                                Msg(
                                    com.rengwuxian.wecompose.data.User(
                                        id = userInfo["username"].toString(),
                                        name = userInfo["petname"].toString(),
                                        R.drawable.avatar_rengwuxian
                                    ), obj["text"].toString()
                                )
                            )
                        } else {
                            msgList.add(
                                Msg(
                                    com.rengwuxian.wecompose.data.User(
                                        id = obj["id1"].toString().toString(),
                                        name = obj["id1"].toString().toString(),
                                        R.drawable.avatar_rengwuxian
                                    ), obj["text"].toString()
                                )
                            )
                        }
                    }
//                    println(msgList)
                    viewModel.chats.add(Chat(com.rengwuxian.wecompose.data.User(it.id, it.name, R.drawable.avatar_rengwuxian), msgList))
                }
            }
        }
    }
}

fun Modifier.percentOffsetX(percent: Float) = this.layout { measurable, constraints ->
    val placeable = measurable.measure(constraints)
    layout(placeable.width, placeable.height) {
        placeable.placeRelative(IntOffset((placeable.width * percent).roundToInt(), 0))
    }
}

/**
 * 增加未读小红点
 */
fun Modifier.unread(read: Boolean, badgeColor: Color) = this
    .drawWithContent {
        drawContent()
        if (!read) {
            drawCircle(
                color = badgeColor,
                radius = 5.dp.toPx(),
                center = Offset(size.width - 1.dp.toPx(), 1.dp.toPx()),
            )
        }
    }


